package jp.dev7.android.util;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public abstract class AbstractDownloadActivity<T> extends Activity implements
		OnClickListener {

	private static final int STATE_FIRST = 0;
	private static final int STATE_LOADING = 1;
	private static final int STATE_COMPLETE = 2;

	protected ProgressBar progressBar;
	protected TextView message;
	protected Button button;
	protected int state = STATE_FIRST;

	private AbstractDownloadWorker<T> downloadWorker;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(getLayout());

		progressBar = (ProgressBar) findViewById(getProgressBarId());
		message = (TextView) findViewById(getMessageId());
		button = (Button) findViewById(getButtonId());

		button.setOnClickListener(this);
	}

	@Override
	protected void onSaveInstanceState(Bundle data) {
		super.onSaveInstanceState(data);
		data.putString("message.text", message.getText().toString());
		data.putBoolean("progressBar.indeterminate",
				progressBar.isIndeterminate());
		data.putInt("progressBar.max", progressBar.getMax());
		data.putInt("progressBar.progress", progressBar.getProgress());
		data.putString("button.text", button.getText().toString());
		data.putInt("state", state);
	}

	@Override
	protected void onRestoreInstanceState(Bundle data) {
		super.onRestoreInstanceState(data);
		message.setText(data.getString("message.text"));
		progressBar.setIndeterminate(data
				.getBoolean("progressBar.indeterminate"));
		progressBar.setMax(data.getInt("progressBar.max"));
		progressBar.setProgress(data.getInt("progressBar.progress"));
		button.setText(data.getString("button.text"));
		state = data.getInt("state");
	}

	@Override
	public void onClick(View v) {
		switch (state) {
		case STATE_FIRST: {
			startDownload();
			break;
		}
		case STATE_LOADING: {
			if (downloadWorker != null) {
				downloadWorker.cancel();
			}

			setResult(RESULT_CANCELED);
			finish();
			break;
		}
		case STATE_COMPLETE: {
			setResult(RESULT_OK);
			finish();
			break;
		}
		}
	}

	private void startDownload() {
		message.setText("ダウンロード中…");
		progressBar.setVisibility(View.VISIBLE);
		button.setText("キャンセル");
		state = STATE_LOADING;

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				Bundle data = msg.getData();
				if (data.getSerializable(Worker.ERROR) != null) {
					Throwable e = (Throwable) data
							.getSerializable(Worker.ERROR);
					message.setText("ダウンロードが失敗しました。");

					Log.e(getClass().toString(), "エラー " + e.toString(), e);
				} else {
					message.setText("ダウンロードが完了しました。");
				}
				onCompleteDownload();
			}
		};

		downloadWorker = getDownloadWorker();
		downloadWorker.execute(handler);
	}

	private void onCompleteDownload() {
		progressBar.setVisibility(View.INVISIBLE);
		button.setText("戻る");
		state = STATE_COMPLETE;
	}

	protected abstract AbstractDownloadWorker<T> getDownloadWorker();

	protected abstract int getButtonId();

	protected abstract int getMessageId();

	protected abstract int getProgressBarId();

	protected abstract int getLayout();
}
